﻿using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System.Text;

namespace RabbitMq.ServerApi.HostService
{
    /// <summary>
    /// 
    /// </summary>
    public class RabbitmqHostService:IHostedService
    {

        /**
         * IHostedService是ASP.NET Core中的一种接口，用于实现长期运行的服务或后台任务，这些任务回在应用程序启动时开始
         * 并在应用程序关闭时结束，这对于定时任务，持续监听队列、维持心跳检测等场景非常有用
         * **/
        public Task StartAsync(CancellationToken cancellationToken)
        {
            //1、创建连接
            var factory = new ConnectionFactory()
            {
                HostName = "localhost",
                Port = 5672,
                Password = "guest",
                UserName = "guest",
                VirtualHost = "/"
            };

            var connection = factory.CreateConnection();

            #region 单消费者(如数单机据统计场景)
            var channel = connection.CreateModel();
            //2、定义队列
            channel.QueueDeclare(queue: "statistics-report",
                                 durable: false,
                                 exclusive: false,
                                 autoDelete: false,
                                 arguments: null
                                 );
            /* 参数的含义：
               exchange：交换器的名字
               type：交换器的类型
               durable：是否定义一个持久化的交换器
               autoDelete：在交换器长时间未被使用的时候，服务器是否自动删除
               internal：是否定义一个内部的交换器，如果交换器是内部的，那么它就不能被客户端直接发布
               arguments：交换器的其他属性(构造参数)
               返回值：声明确认方法，用于指示已成功声明了交换器*/

            var consumer = new EventingBasicConsumer(channel);
            consumer.Received += (sender, args) =>
            {
                Console.WriteLine($"sender:{sender}");
                Console.WriteLine($", args:{args}");
                var body = args.Body;
                var message = Encoding.UTF8.GetString(body.ToArray());
                //处理业务逻辑

                Console.WriteLine("数据统计完成...{0}", message);
            };

            //3.消费队列（推模式）
            channel.BasicConsume(
                queue: "statistics-report",
                autoAck: true, 
                consumer: consumer);
            /**
             * 
             * 参数含义：
                queue：消息队列的名称
                autoAck：为了确保消息不会丢失，RabbitMQ支持消息应答。消费者发送一个消息应答，告诉RabbitMQ这个消息已经接收并且处理完毕了。RabbitMQ就可以删除它了。
                arguments：设置消费者的其他参数
                deliverCallback：（消息传递时回调）设置消费者的回调参数。用来处理RabbitMQ推送过来的消息比如DefaultConsumer，使用时需要客户端重写其中的方法
                cancelCallback：消费者被取消时回调
                shutdownSignalCallback：当通道/连接关闭时回调 
             * 
             * **/

            #endregion

            Console.WriteLine("rabbitmq开始监听......");
            return Task.CompletedTask;

        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            Console.WriteLine("任务已停止...");
            throw new NotImplementedException();
        }


    }
}
